using System;
using System.Collections.Generic;
using App.Modelo.Interfaces;
using NHibernate;
using NHibernate.Criterion;

namespace App.Controlador
{
    class InternalRepositorio : IRepositorio
    {
        private ISession _activeSession;

        public InternalRepositorio(ISession Session)
        {
            _activeSession = Session;
        }

        public ISessionFactory SessionFactory
        {
            get
            {
                throw new Exception("Not implemented");
            }
        }

        public void Refresh(object obj)
        {
            _activeSession.Refresh(obj);
        }

        #region Session Methods


        public object GetSessionId()
        {
            var c = _activeSession.Connection.CreateCommand();
            c.CommandText = "SELECT @@SPID AS session_id";
            return c.ExecuteScalar();
        }

        public System.Data.IDbConnection Connection
        {
            get
            {
                return _activeSession != null ? _activeSession.Connection : null;
            }
        }

        public void OpenSession()
        {
        }

        public void FlushSession()
        {
        }

        public void CloseSession()
        {
        }

        public ISession Session
        {
            get
            {
                return _activeSession;
            }
        }

        public void BeginTransaccion()
        {
        }

        public void CommitTransaction()
        {
        }

        public void RoolbackTransaction()
        {
        }
        #endregion



        #region Object Methods

        public void SaveObject(object obj)
        {
            _activeSession.Save(obj);
        }

        public void UpdateObject(object obj)
        {
            _activeSession.Update(obj);
        }

        public void DeleteObject(object obj)
        {
            _activeSession.Delete(obj);
        }

        #endregion


        #region Metodos Extendidos

        #region GetById
        public T GetById<T>(object id)
        {
            return (T)_activeSession.Get(typeof(T), id);
        }
        #endregion

        #region GetList
        public IList<T> GetList<T>(string _hql)
        {
            return _activeSession.CreateQuery(_hql).List<T>();
        }

        public IList<T> GetList<T>(string _hql, IDictionary<string, object> _param)
        {
            IQuery query = _activeSession.CreateQuery(_hql);

            foreach (KeyValuePair<string, object> oitem in _param)
            {
                if (oitem.Value == null)
                {
                    query.SetParameter(Convert.ToString(oitem.Key), null, NHibernateUtil.Int32);
                }
                else
                {
                    query.SetParameter(Convert.ToString(oitem.Key), oitem.Value);
                }
            }

            return query.List<T>();
        }

        public IList<T> GetList<T>(string _hql, IDictionary<string, string> _param)
        {
            IQuery query = _activeSession.CreateQuery(_hql);

            foreach (KeyValuePair<string, string> oitem in _param)
            {
                if (oitem.Value == null)
                {
                    query.SetParameter(oitem.Key, null, NHibernateUtil.Int32);
                }
                else
                {
                    query.SetParameter(oitem.Key, oitem.Value);
                }
            }

            return query.List<T>();
        }


        public IList<T> GetList<T>(string filterPropertyName, string filterPropertyValue)
        {
            return _activeSession
                .CreateCriteria(typeof(T))
                .Add(Restrictions.Eq(filterPropertyName, filterPropertyValue))
                .List<T>();
        }

        public IList<T> GetList<T>(string filterPropertyName, object filterPropertyValue)
        {
            return _activeSession
                .CreateCriteria(typeof(T))
                .Add(Restrictions.Eq(filterPropertyName, filterPropertyValue))
                .List<T>();
        }
        #endregion

        public T Get<T>(string filterPropertyName, object filterPropertyValue)
        {
            return _activeSession
                .CreateCriteria(typeof(T))
                .Add(Restrictions.Eq(filterPropertyName, filterPropertyValue))
                .UniqueResult<T>();
        }

        public IList<T> GetAll<T>()
        {
            if (_activeSession == null || (_activeSession != null && !_activeSession.IsOpen))
                this.OpenSession();
            ICriteria crit = _activeSession.CreateCriteria(typeof(T));
            return crit.List<T>();

        }
        #endregion

        #region IRepositorio Members

        public event EventHandler<TriggerEventHandler> FlushData;

        #endregion
    }
}